//责任链模式  chain of responsibility
//使多个对象都有机会处理请求，从而避免请求的发送者和接收者之间的耦合关系
//使得多个对象连成一个链，知道有对象能够处理请求位置
#include <iostream>
#include <memory>
#include <string>

//请求，请求需要分为各种级别，不同级别的管理者对应不同的请求处理权限
struct Request
{
public:
    using ptr=std::shared_ptr<Request>;
    
    enum Level{
        AskLevel=0,
        Reimburse,
        Funding,        
        AddSalary,
        ApplyLeave
    };
    Request(const std::string& name, const std::string& content,Level level):
    m_name(name),m_content(content),m_level(level){}
    //请假名字，内容和类别
    std::string m_name;
    std::string m_content;
    Level m_level;
};


//抽象的管理者，可以处理请求，不同管理者处理不同级别的请求
class Manager
{
public:
    using ptr=std::shared_ptr<Manager>;
    Manager(const std::string& name):m_name(name){}
    virtual ~Manager(){}
    virtual void handle(Request::ptr request)=0;
    //设置管理者的上级，当自己无法处理该请求时，交给上级处理
    void setSuprior(Manager::ptr suprior)
    {
        m_suprior=suprior;
    }
protected:
    std::string m_name;
    Manager::ptr m_suprior;
};

class ManagerOne:public Manager
{
public:
    using ptr=std::shared_ptr<ManagerOne>;
    ManagerOne(const std::string& name):Manager(name){}
    ~ManagerOne(){}
    virtual void handle(Request::ptr request) override
    {
        if (request->m_level<2)
        {
            std::cout<<"我是主管1,我叫"<<Manager::m_name<<std::endl;
            std::cout<<request->m_name<<"的请求:"<<request->m_content<<std::endl;
            std::cout<<"我批准了"<<std::endl;
        }
        else{
            std::cout<<"这个请求，主管1批不了，交给我的上级处理"<<std::endl;
            Manager::m_suprior->handle(request);
        }        
    }
};


class ManagerTwo:public Manager
{
public:
    using ptr=std::shared_ptr<ManagerTwo>;
    ManagerTwo(const std::string& name):Manager(name){}
    ~ManagerTwo(){}
    virtual void handle(Request::ptr request) override
    {
        if (request->m_level<3)
        {
            std::cout<<"我是主管2,我叫"<<Manager::m_name<<std::endl;
            std::cout<<request->m_name<<"的请求:"<<request->m_content<<std::endl;
            std::cout<<"我批准了"<<std::endl;
        }
        else{
            std::cout<<"这个请求，主管2批不了，交给我的上级处理"<<std::endl;
            Manager::m_suprior->handle(request);
        }        
    }
};

class ManagerThree:public Manager
{
public:
    using ptr=std::shared_ptr<ManagerThree>;
    ManagerThree(const std::string& name):Manager(name){}
    ~ManagerThree(){}
    virtual void handle(Request::ptr request) override
    {
        if (request->m_level<5)
        {
            std::cout<<"我是主管3,我叫"<<Manager::m_name<<std::endl;
            std::cout<<request->m_name<<"的请求:"<<request->m_content<<std::endl;
            std::cout<<"我批准了"<<std::endl;
        }
        else{
            std::cout<<"这个请求，我批不了，交给我的上级处理"<<std::endl;
            Manager::m_suprior->handle(request);
        }        
    }
};

int main(int argc, char** argv)
{
    Request::ptr request(new Request("daniel","我要走人",Request::ApplyLeave));
    ManagerOne::ptr hz(new ManagerOne("Jimmy"));
    ManagerTwo::ptr wm(new ManagerTwo("John"));
    ManagerThree::ptr tlx(new ManagerThree("Royal"));
    hz->setSuprior(wm);
    wm->setSuprior(tlx);
    hz->handle(request);
    return 0;
}